﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;
using Dapper;

namespace Micro.Extensions.Data
{
    public interface IDbContext
    {
        /// <summary>
        /// 添加操作
        /// </summary>
        /// <param name="func"></param>
        void AddCommand(Func<IDbConnection, IDbTransaction, Task<int>> func);
        /// <summary>
        /// 事务提交
        /// </summary>
        /// <returns></returns>
        Task<int> CommitAsync();

        #region Query

        /// <summary>
        /// 简单查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <param name="transaction"></param>
        /// <param name="commandTimeout"></param>
        /// <param name="readMaster"></param>
        /// <returns></returns>
        T Get<T>(object id, IDbTransaction transaction = null, int? commandTimeout = null, bool readMaster = false) where T : class;

        /// <summary>
        /// 查询集合
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="sql">sql</param>
        /// <param name="param">参数</param>
        /// <param name="transaction">事务</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="readMaster">默认读从库</param>
        /// <returns>集合</returns>
        Task<IEnumerable<T>> QueryAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, bool readMaster = false);
        /// <summary>
        ///  查询第一个
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="sql">sql</param>
        /// <param name="param">参数</param>
        /// <param name="transaction">事务</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="readMaster">默认读从库</param>
        /// <returns>实体对象</returns>
        Task<T> QueryFirstAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, bool readMaster = false);
        /// <summary>
        ///  查询第一个，没有返回null
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="sql">sql</param>
        /// <param name="param">参数</param>
        /// <param name="transaction">事务</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="readMaster">默认读从库</param>
        /// <returns>实体对象</returns>
        Task<T> QueryFirstOrDefaultAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, bool readMaster = false);
        /// <summary>
        ///  查询一个，没有报错
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="sql">sql</param>
        /// <param name="param">参数</param>
        /// <param name="transaction">事务</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="readMaster">默认读从库</param>
        /// <returns>实体对象</returns>
        Task<T> QuerySingleAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, bool readMaster = false);
        /// <summary>
        ///  查询一个，没有返回null
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="sql">sql</param>
        /// <param name="param">参数</param>
        /// <param name="transaction">事务</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="readMaster">默认读从库</param>
        /// <returns>实体对象</returns>
        Task<T> QuerySingleOrDefaultAsync<T>(string sql, object param = null, IDbTransaction transaction = null,
            int? commandTimeout = null, bool readMaster = false);
        /// <summary>
        /// 查询多个 返回多个查询集合
        /// </summary>
        /// <typeparam name="T">返回类型</typeparam>
        /// <param name="sql">sql</param>
        /// <param name="param">参数</param>
        /// <param name="transaction">事务</param>
        /// <param name="commandTimeout">超时时间</param>
        /// <param name="readMaster">默认读从库</param>
        /// <returns>多个查询集合</returns>
        Task<SqlMapper.GridReader> QueryMultipleAsync(string sql, object param = null,
            IDbTransaction transaction = null, int? commandTimeout = null, bool readMaster = false);
        #endregion
    }
}